package com.tian.view.anim.view_group_child

import android.animation.LayoutTransition
import android.animation.ObjectAnimator
import android.animation.PropertyValuesHolder
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import com.google.android.material.button.MaterialButton
import com.tian.view.databinding.FragmentAnimateLayoutChangesBinding

/**
 * @author tiansongtao, Email:tiansongtao@up366.com
 * @date 2022/12/29 14:43
 */
class LayoutTransitionFragemnt : Fragment() {

    private lateinit var b: FragmentAnimateLayoutChangesBinding
    private var index = 0

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        b = FragmentAnimateLayoutChangesBinding.inflate(inflater)
        return b.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initView()
    }

    private fun initView() {
        /**
         * b.llAnim 设置了 android:animateLayoutChanges="true"
         * 所以他又 layoutTransition, 这里我们可以从新给他设置动画时间
         */
        b.llAnim.layoutTransition.setDuration(2000)
        b.mbtAdd.setOnClickListener {
            val view = createButton(false)
            b.llNoAnim.addView(view, 0)
            val v = createButton(true)
            b.llAnim.addView(v, 0)
            index++
        }
        b.mbtRemove.setOnClickListener {
            if (b.llNoAnim.childCount > 0) {
                b.llNoAnim.removeViewAt(0)
            }
            if (b.llAnim.childCount > 0) {
                b.llAnim.removeViewAt(0)
            }
        }

        //为 ViewGroup添加自定义 LayoutTransition
        b.llNoAnim.layoutTransition = createLayoutTransition()

        /**
         * LayoutTransition还提供了监听函数
         */
        b.llNoAnim.layoutTransition.addTransitionListener(object : LayoutTransition.TransitionListener {
            /**
             * @param transition 当前执行的 LayoutTransition
             * @param container 当前应用 LayoutTransition的ViewGroup
             * @param view 当前在做动画的View
             * @param transitionType 当前执行动画的类型 [LayoutTransition.APPEARING]
             */
            override fun startTransition(transition: LayoutTransition?, container: ViewGroup?, view: View?,
                transitionType: Int) {

            }

            override fun endTransition(transition: LayoutTransition?, container: ViewGroup?, view: View?,
                transitionType: Int) {

            }

        })
    }

    /**
     * [LayoutTransition.setAnimator]
     * transitionType:
     *  [LayoutTransition.APPEARING]: 添加子控件时的动画
     *  [LayoutTransition.DISAPPEARING]: 删除子控件时的动画
     *  [LayoutTransition.CHANGE_APPEARING]: 添加子view时，其他子view的动画
     *  [LayoutTransition.CHANGE_DISAPPEARING]: 删除子View时，其他子view的动画
     *  [LayoutTransition.CHANGE]: 表示布局改变的动画，而不是添加或删除导致改变的动画
     *
     */
    @SuppressLint("ObjectAnimatorBinding")
    private fun createLayoutTransition(): LayoutTransition {
        // 可以查看LayoutTransition的构造函数，默认动画的构建方式，替换了默认动画就是我们自定义的动画
        val layoutTransition = LayoutTransition()
        // 添加和删除的动画可以使用 ObjectAnimator来设置
        val inAnim = ObjectAnimator.ofFloat(null, "rotationY", 0f, 360f, 0f)
        layoutTransition.setAnimator(LayoutTransition.APPEARING, inAnim)
        val outAnim = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f)
        layoutTransition.setAnimator(LayoutTransition.DISAPPEARING, outAnim)

        /**
         * [LayoutTransition.CHANGE_APPEARING] [LayoutTransition.CHANGE_DISAPPEARING] 必须使用
         * PropertyValuesHolder来创建动画才会在LayoutTransition中执行。
         *
         * 这两个属性的动画还必须先定义两个left 和 top
         *  val pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1)
         *  val pvhTop = PropertyValuesHolder.ofInt("top", 0, 1)
         * 要不然动画不会执行，一般我们 left top right bottom 都添加 不然控件会不自然
         */
        val pvhLeft = PropertyValuesHolder.ofInt("left", 0, 1)
        val pvhTop = PropertyValuesHolder.ofInt("top", 0, 1)
        val pvhRight = PropertyValuesHolder.ofInt("right", 0, 1)
        val pvhBottom = PropertyValuesHolder.ofInt("bottom", 0, 1)
        val scaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f)
        val inAnimChange = ObjectAnimator.ofPropertyValuesHolder(null as Any?, pvhLeft, pvhTop, pvhRight, pvhBottom,
                scaleX)
        layoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, inAnimChange)

        layoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, inAnimChange.clone())

        layoutTransition.setDuration(2000)
        return layoutTransition
    }

    private fun createButton(anim: Boolean): View {
        val bt = MaterialButton(requireContext())
        val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
        bt.layoutParams = lp
        bt.text = if (anim) "默认动画-${index + 1}" else "自定义动画-${index + 1}"
        bt.gravity = Gravity.CENTER
        return bt
    }
}